package gb;

import gb.struct.Pair;
import gb.struct.Polynomial;

import java.util.ArrayList;


public class Algorithm {
    
	/**
	 * original algorithm by buchberger
	 * @param mySet used to create GB
	 * @return the GB
	 */
    public static PolySet run(PolySet mySet) {
        PolySet G = (PolySet) mySet.clone(); //step 1
        ArrayList<Pair> m = initM(mySet); //step 2
        Pair pq;
        
        while ((pq = extractPair(m)) != null) {
            System.out.println("temp: " + pq);
            
            Polynomial S = SPoly.compute(pq.getP1(), pq.getP2());
            if (S.size() > 0) {
                S.sort();
                System.out.println("s: " + S);
                Polynomial h = Utils.normalForm(S, G);
                System.out.println("h: " + h);

                if (h != null && h.size() > 0) {
                    addPairsWith(h, G, m);
                    G.addPoly(h);
                }
            }
            System.out.println("grobner: " + G);
        }
        
        return G;
    }
    
    private static void addPairsWith(Polynomial h, PolySet set, ArrayList<Pair> m) {
        for (int i = 0; i < set.size(); i++) {
            Pair temp = new Pair(h, set.getPoly(i));
            if (! m.contains(temp)) {
                m.add(temp);
            }
        }
    }

    private static Pair extractPair(ArrayList<Pair> m) {
        if (m.size() > 0) {
            return m.remove(0);
        }
        return null;
    }
    
    private static ArrayList<Pair> initM(PolySet mySet) {
    	ArrayList<Pair>m = new ArrayList<Pair>();
        for (int i = 0; i < mySet.size(); i++) {
            for (int j = i + 1; j < mySet.size(); j++) {
            	m.add(new Pair(mySet.getPoly(i), mySet.getPoly(j)));
            }
        }
        return m;
    }
}
